﻿#pragma once
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#pragma comment(lib, "comctl32.lib")

#define  WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <commctrl.h>
#include <tchar.h>
#include <vector>
#include "_H_SOCKET.h"
#include "Global_Define.h"
#include "tinyxml/tinyxml.h"
#include "resource.h"

using namespace std;


HWND g_hWnd_Login = NULL;		//登录窗口句柄
LoginUserInfo usrInfo[MAX_HISLOGIN_COUNT];//用户储存登录用户信息

/************************************************************************/
/* 函数声明														        */
/************************************************************************/
BOOL InitControls();									//初始化公共控件
void InitControlsProperty();							//初始化控件属性
void ShowTip(HWND hIDControl, LPCTSTR lpString);		//显示提示文本
void LoadLoginUser();

//登录窗口处理函数
int CALLBACK LoginProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	//创建登录窗体
	g_hWnd_Login = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_LOGIN_DLG), NULL, LoginProc);
	ShowWindow(g_hWnd_Login, SW_SHOW);
	UpdateWindow(g_hWnd_Login);

	//消息循环
	MSG msg;
	while (GetMessage(&msg, NULL, NULL, NULL))
	{
		if ( !IsDialogMessage(g_hWnd_Login, &msg) )
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return 0;
}

//登录窗口处理函数
int CALLBACK LoginProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	//操作登录历史记录的XML文档对象
	TiXmlDocument *pDoc = new TiXmlDocument(XML_HIS_USERS);
	TiXmlElement *pElemRoot;
	
	TiXmlElement *pNewElement_Save = new TiXmlElement("user");

	//////////////////////////////////////////////////////////////////////////

	char szCurUsername[MAX_USERNAME_LEN] = {0};		//当前选中的用户名
	char szUsernameTemp[MAX_USERNAME_LEN] = {0};
	char szPasswordTemp[MAX_PASSWORD_LEN] = {0};
	int nRemPass = 0;
	int nAutoLogin = 0;

	switch(uMsg)
	{
	case WM_INITDIALOG:
		if (InitControls() == FALSE)
		{
			MessageBox(g_hWnd_Login, _T("初始化程序失败！请尝试重新安装以解决这个问题。"), _T("错误"), MB_ICONERROR);
			PostQuitMessage(EXIT_FAILURE);
		}

		return TRUE;
	case WM_SHOWWINDOW:
		InitControlsProperty();
		ShowTip(GetDlgItem(g_hWnd_Login, IDC_TIP_STATIC), _T(" 请输入帐号密码。"));
		LoadLoginUser();

		return TRUE;
	case WM_CLOSE:
		PostQuitMessage(EXIT_SUCCESS);
		return TRUE;

	case WM_COMMAND:
		switch(LOWORD(wParam))
		{

		/*登录按钮*/
		case IDC_LOGIN_BTN:

			GetWindowTextA(GetDlgItem(g_hWnd_Login, IDC_USERNAME_CMB), szUsernameTemp, MAX_USERNAME_LEN);
			GetWindowTextA(GetDlgItem(g_hWnd_Login, IDC_PASSWORD_EDIT), szPasswordTemp, MAX_PASSWORD_LEN);
			nRemPass = SendDlgItemMessage(g_hWnd_Login, IDC_REMPASSWORD_CHK, BM_GETCHECK, 0, 0);
			nAutoLogin = SendDlgItemMessage(g_hWnd_Login, IDC_AUTOLOGIN_CHK, BM_GETCHECK, 0, 0);
			
			//检测用户名文本框是否为空
			if (strlen(szUsernameTemp) == 0)
			{
				ShowTip(GetDlgItem(g_hWnd_Login, IDC_TIP_STATIC), _T("用户名不能为空！"));
				SetFocus(GetDlgItem(g_hWnd_Login, IDC_USERNAME_CMB));
				return TRUE;
			}

			//检测密码文本框是否为空
			if (strlen(szPasswordTemp) == 0)
			{
				ShowTip(GetDlgItem(g_hWnd_Login, IDC_TIP_STATIC), _T("密码不能为空！"));
				SetFocus(GetDlgItem(g_hWnd_Login, IDC_PASSWORD_EDIT));
				return TRUE;
			}

			//打开XML文件
			if (pDoc->LoadFile() == true)
			{
				//获得根元素，即Login，不存在则创建
				pElemRoot = pDoc->RootElement();
				if (pElemRoot == NULL)
				{
					TiXmlElement *pRoot = new TiXmlElement("Login");
					pDoc->LinkEndChild(pRoot);
					pDoc->SaveFile();
				}

			} else {
				//如果XML文件不存在，则创建
				TiXmlDeclaration *pNewDel_Create = new TiXmlDeclaration("1.0", "UTF-8", "");
				TiXmlElement *pNewRoot_Create = new TiXmlElement("Login");
				pDoc->LinkEndChild(pNewDel_Create);
				pDoc->LinkEndChild(pNewRoot_Create);
				pDoc->SaveFile();
				pElemRoot = pDoc->RootElement();
			}

			//遍历历史登录用户信息，判断当前用户名是否为新输入的
			for (int i = 0; i != MAX_HISLOGIN_COUNT; i++)
			{
				if ( strcmp(usrInfo[i].szUsername, szUsernameTemp) == 0)
				{
					//保存新的用户名
					memcpy(usrInfo[i].szUsername, szUsernameTemp, MAX_USERNAME_LEN);
					memcpy(usrInfo[i].szPassword, szPasswordTemp, MAX_PASSWORD_LEN);
					usrInfo[i].nRemPassword = nRemPass;
					usrInfo[i].nAutoLogin = nAutoLogin;

					//清空XML的根节点
					pElemRoot->Clear();

					//单独保存更新后的元素，使其在最前
					TiXmlElement *pNewElement_Update = new TiXmlElement("user");
					pElemRoot->LinkEndChild(pNewElement_Update);
					pNewElement_Update->SetAttribute("username", usrInfo[i].szUsername);
					pNewElement_Update->SetAttribute("password", usrInfo[i].szPassword);
					pNewElement_Update->SetAttribute("rempass", usrInfo[i].nRemPassword);
					pNewElement_Update->SetAttribute("autologin", usrInfo[i].nAutoLogin);

					//遍历更新后的登录用户信息结构体，写入XML
					for (int j = 0; j != MAX_HISLOGIN_COUNT; j++)
					{
						if ( strlen(usrInfo[j].szUsername) > 0 && i != j )
						{
							TiXmlElement *pNewElm = new TiXmlElement("user");
							pElemRoot->LinkEndChild(pNewElm);
							pNewElm->SetAttribute("username", usrInfo[j].szUsername);
							pNewElm->SetAttribute("password", usrInfo[j].szPassword);
							pNewElm->SetAttribute("rempass", usrInfo[j].nRemPassword);
							pNewElm->SetAttribute("autologin", usrInfo[j].nAutoLogin);
						}
					}
					pDoc->SaveFile();
					LoadLoginUser();
					return TRUE;
				}
			}

			//保存XML
			pElemRoot->Clear();
			pElemRoot->LinkEndChild(pNewElement_Save);
			pNewElement_Save->SetAttribute("username", szUsernameTemp);
			pNewElement_Save->SetAttribute("password", szPasswordTemp);
			pNewElement_Save->SetAttribute("rempass", nRemPass);
			pNewElement_Save->SetAttribute("autologin", nAutoLogin);

			for (int k = 0; k != MAX_HISLOGIN_COUNT; k++)
			{
				if ( strlen(usrInfo[k].szUsername) > 0 )
				{
					TiXmlElement *pNewElement_Save = new TiXmlElement("user");
					pElemRoot->LinkEndChild(pNewElement_Save);
					pNewElement_Save->SetAttribute("username", usrInfo[k].szUsername);
					pNewElement_Save->SetAttribute("password", usrInfo[k].szPassword);
					pNewElement_Save->SetAttribute("rempass", usrInfo[k].nRemPassword);
					pNewElement_Save->SetAttribute("autologin", usrInfo[k].nAutoLogin);
				}
			}
			pDoc->SaveFile();
			LoadLoginUser();
			
			return TRUE;

		/*退出按钮*/
		case IDC_EXIT_BTN:
			if (MessageBox(g_hWnd_Login, _T("确认要退出聊天室吗？"), _T("提示"), MB_YESNO | MB_ICONINFORMATION) == IDYES)
				PostQuitMessage(EXIT_SUCCESS);
			return TRUE;

		/*用户名下拉框*/
		case IDC_USERNAME_CMB:

			//项目变更的情况下
			if ( HIWORD(wParam) == CBN_SELCHANGE )
			{
				int nCurSel = SendDlgItemMessage(g_hWnd_Login, IDC_USERNAME_CMB, CB_GETCURSEL, 0, 0);
				SendDlgItemMessageA(g_hWnd_Login, IDC_USERNAME_CMB, CB_GETLBTEXT, nCurSel, (LPARAM)szCurUsername);

				for (int i = 0; i != MAX_HISLOGIN_COUNT; i++)
				{
					//获取该用户名密码等信息
					if ( strcmp(usrInfo[i].szUsername, szCurUsername) == 0 )
					{
						SetWindowTextA(GetDlgItem(g_hWnd_Login, IDC_PASSWORD_EDIT), usrInfo[i].szPassword);
						SendDlgItemMessage(g_hWnd_Login, IDC_REMPASSWORD_CHK, BM_SETCHECK, usrInfo[i].nRemPassword, 0);
						SendDlgItemMessage(g_hWnd_Login, IDC_AUTOLOGIN_CHK, BM_SETCHECK, usrInfo[i].nAutoLogin, 0);
					}
				}
			}

			return TRUE;

		/*自动登录复选框*/
		case IDC_AUTOLOGIN_CHK:
			if ( HIWORD(wParam) == BN_CLICKED )
			{
				//获取复选框状态
				int iCheckState = SendDlgItemMessage(g_hWnd_Login, IDC_AUTOLOGIN_CHK, BM_GETCHECK, 0, 0);
				if ( iCheckState == BST_CHECKED )
				{
					//同时选中“记住密码”
					SendDlgItemMessage(g_hWnd_Login, IDC_REMPASSWORD_CHK, BM_SETCHECK, BST_CHECKED, 0);
				}
			}

			return TRUE;

		}
		return TRUE;
	}

	return FALSE;
}

//初始化公共控件
BOOL InitControls()
{
	INITCOMMONCONTROLSEX InitCtrls;
	InitCtrls.dwICC = ICC_LINK_CLASS | ICC_WIN95_CLASSES;
	InitCtrls.dwSize = sizeof(InitCtrls);
	return ::InitCommonControlsEx(&InitCtrls);
}

//显示提示文本
void ShowTip(HWND hIDControl, LPCTSTR lpString)
{
	SetWindowText(hIDControl, lpString);
}

//控件属性初始化
void InitControlsProperty()
{
	//设置用户名下拉框的最大输入长度
	DWORD dwStyle = GetWindowLong(GetDlgItem(g_hWnd_Login, IDC_USERNAME_CMB), GWL_STYLE);
	dwStyle |= CBS_AUTOHSCROLL;
	SetWindowLong(GetDlgItem(g_hWnd_Login, IDC_USERNAME_CMB), GWL_STYLE, dwStyle);
	SendDlgItemMessage(g_hWnd_Login, IDC_USERNAME_CMB, CB_LIMITTEXT, (WPARAM)MAX_USERNAME_LEN, 0);

	//设置密码文本框最大输入长度
	SendDlgItemMessage(g_hWnd_Login, IDC_PASSWORD_EDIT, EM_LIMITTEXT, (WPARAM)MAX_PASSWORD_LEN, 0);
}

//加载历史登录列表
void LoadLoginUser()
{
	//创建一个XML的文档对象
	TiXmlDocument *pDoc = new TiXmlDocument(XML_HIS_USERS);

	int iCntUser = 0; //储存历史登录用户计数

	if ( pDoc->LoadFile() == true )
	{
		//获得根元素，即LoginHistory
		TiXmlElement *pElemRoot = pDoc->RootElement();

		//判断空指针
		if (pElemRoot == NULL) return;

		//循环获取user节点
		SendDlgItemMessage(g_hWnd_Login, IDC_USERNAME_CMB, CB_RESETCONTENT, 0, 0);
		for (TiXmlElement *pUser = pElemRoot->FirstChildElement(); pUser; pUser = pUser->NextSiblingElement())
		{
			memcpy(usrInfo[iCntUser].szUsername, pUser->Attribute("username"), MAX_USERNAME_LEN);
			memcpy(usrInfo[iCntUser].szPassword, pUser->Attribute("password"), MAX_USERNAME_LEN);
			usrInfo[iCntUser].nRemPassword = atoi(pUser->Attribute("rempass"));
			usrInfo[iCntUser].nAutoLogin = atoi(pUser->Attribute("autologin"));
			iCntUser++;

			//添加到下框拉
			SendDlgItemMessageA(g_hWnd_Login, IDC_USERNAME_CMB, CB_ADDSTRING, 0, (LPARAM)pUser->Attribute("username"));

			//达到了要保存的历史记录数量限制则退出循环
			if (iCntUser == MAX_HISLOGIN_COUNT)
			{
				break;
			}
		}
	}

	//人性化细节设置
	if (iCntUser > 0)
	{
		SendDlgItemMessage(g_hWnd_Login, IDC_USERNAME_CMB, CB_SETCURSEL, 0, 0);
		SetWindowTextA(GetDlgItem(g_hWnd_Login, IDC_PASSWORD_EDIT), usrInfo[0].szPassword);
		SendDlgItemMessage(g_hWnd_Login, IDC_REMPASSWORD_CHK, BM_SETCHECK, usrInfo[0].nRemPassword, 0);
		SendDlgItemMessage(g_hWnd_Login, IDC_AUTOLOGIN_CHK, BM_SETCHECK, usrInfo[0].nAutoLogin, 0);
		SendDlgItemMessage(g_hWnd_Login, IDC_PASSWORD_EDIT, EM_SETSEL, 0, -1);
	} else {
		SetFocus(GetDlgItem(g_hWnd_Login, IDC_USERNAME_CMB));
	}
}
